﻿using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;

namespace OpenHunauEleEmailSender
{
	internal partial class Program
	{

		static void Main()
		{
			if (!File.Exists(Config.DefConfigFile))
			{
				Config.CreateConfig();
				Console.WriteLine($"配置文件{Config.DefConfigFile}已经生成，请正确填写配置文件。");
				return;
			}
			if (!Config.LoadConfig())
			{
				Console.WriteLine("错误: 没有正确的配置文件！若填写混乱，删除配置文件可重新生成默认配置文件。");
				return;
			}
			Console.WriteLine($"配置文件已读取。");
			if (!SendMailSys.Init())
			{
				Console.WriteLine("错误: 测试邮件发送失败，请检查邮件服务器是否正确配置。");
				return;
			}
			var emails = Config.Inst.RecipientsEmails.Split(',');
			int pos = 1;
			foreach (var item in emails)
			{
				var email = item.Trim();
				Recipients.Add(email);
				Console.WriteLine($"{pos++}.成功添加收件人邮箱：【{email}】");
			}
			Console.WriteLine($"发件人邮箱：【{Config.Inst.SenderEmailAddress}】");
			Console.WriteLine("<><><><><><><><><><><><><><><>");
			Console.WriteLine("发件提醒服务已开始");
			Console.WriteLine("------------------------------");
			MainLoop().Wait();
		}

		public static async Task<string> InformRequestAsync(string token)
		{
			try
			{
				var url = Encoding.UTF8.GetString(Convert.FromBase64String(token));
				var client = new HttpClient();
				var message = new HttpRequestMessage(HttpMethod.Get, url);
				var result = await client.SendAsync(message);
				string? str = await result.Content.ReadAsStringAsync();
				if (str is null)
					return "{}";
				if (url.Contains('#') && str.Contains("<!DOCTYPE html>"))
				{
					var jumpUrl = JumpUrlRegex().Match(str).Groups["JumpUrl"].Value;
					if (string.IsNullOrEmpty(jumpUrl))
						return "{}";
					url = jumpUrl + url.Split('#')[^1];
					message = new HttpRequestMessage(HttpMethod.Get, url);
					result = await client.SendAsync(message);
					str = await result.Content.ReadAsStringAsync();
					if (str is null)
						return "{}";
				}
				return str;
			}
			catch
			{
				return "{}";
			}
		}

		private const int DelaySeconds = 5 * 60;
		private const double DangerousMoney = 5;
		private const double UrgencyMoney = 1;

		private static async Task MainLoop()
		{
			double last_Ele_Lightings_Money = DangerousMoney;
			double last_Ele_AirConditioner_Money = DangerousMoney;
			while (true)
			{
				Console.WriteLine($"[{System.DateTime.Now:G}]");
				try
				{
					if (!string.IsNullOrEmpty(Config.Inst.EleLightingsGetterToken))
					{
						var ele_Lightings_Json = await InformRequestAsync(Config.Inst.EleLightingsGetterToken);
						ResultBody? ele_Lightings_Obj = JsonSerializer.Deserialize(ele_Lightings_Json, AppJsonSerializerContext.Default.ResultBody);
						Console.Write("照明电费： ");
						if (ele_Lightings_Obj == null || (ele_Lightings_Obj.success != true) || ele_Lightings_Obj.resultData.eledetail is null)
						{
							Console.WriteLine("获取失败！");
						}
						else
						{
							var ele_Lightings_MoneyStr = ele_Lightings_Obj.resultData.eledetail.ToString();
							Console.WriteLine(ele_Lightings_MoneyStr);
							if (double.TryParse(ele_Lightings_MoneyStr, out double ele_Lightings_Money))
							{
								try
								{
									if (last_Ele_Lightings_Money >= UrgencyMoney && ele_Lightings_Money < UrgencyMoney)
									{
										InformUser("[照明电费提醒]", $"照明电费已不足{UrgencyMoney}元！请充值！");
									}
									else if (last_Ele_Lightings_Money >= DangerousMoney && ele_Lightings_Money < DangerousMoney)
									{
										InformUser("[照明电费告急]", $"照明电费已不足{DangerousMoney}元，请及时充值！");
									}
									last_Ele_Lightings_Money = ele_Lightings_Money;
								}
								catch (Exception ex)
								{
									Console.WriteLine($"[发送照明电费消息失败] {ex.Message}");
									File.AppendAllText("./SendEleMsg.log", $"[发送照明电费消息失败]{ex.Message}\n" + $"[{System.DateTime.Now:G}]\n" + ex.StackTrace + "\n");
								}
							}
							else Console.WriteLine("[照明电费非数字]");
						}
					}
					if (!string.IsNullOrEmpty(Config.Inst.EleAirConditionerGetterToken))
					{
						var ele_AirConditioner_Json = await InformRequestAsync(Config.Inst.EleAirConditionerGetterToken);
						ResultBody? ele_AirConditioner_Obj = JsonSerializer.Deserialize(ele_AirConditioner_Json, AppJsonSerializerContext.Default.ResultBody);
						Console.Write("空调电费： ");
						if (ele_AirConditioner_Obj == null || (ele_AirConditioner_Obj.success != true) || ele_AirConditioner_Obj.resultData.eledetail is null)
						{
							Console.WriteLine("获取失败！");
						}
						else
						{
							var ele_AirConditioner_MoneyStr = ele_AirConditioner_Obj.resultData.eledetail.ToString();
							Console.WriteLine(ele_AirConditioner_MoneyStr);
							if (double.TryParse(ele_AirConditioner_MoneyStr, out double ele_AirConditioner_Money))
							{
								try
								{
									if (last_Ele_AirConditioner_Money >= UrgencyMoney && ele_AirConditioner_Money < UrgencyMoney)
									{
										InformUser("[空调电费提醒]", $"空调电费已不足{UrgencyMoney}元！请充值！");
									}
									else if (last_Ele_AirConditioner_Money >= DangerousMoney && ele_AirConditioner_Money < DangerousMoney)
									{
										InformUser("[空调电费告急]", $"空调电费已不足{DangerousMoney}元，请及时充值！");
									}
									last_Ele_AirConditioner_Money = ele_AirConditioner_Money;
								}
								catch (Exception ex)
								{
									Console.WriteLine($"[发送空调电费消息失败] {ex.Message}");
									File.AppendAllText("./SendEleMsg.log", $"[发送空调电费消息失败]{ex.Message}\n" + $"[{System.DateTime.Now:G}]\n" + ex.StackTrace + "\n");
								}
							}
							else Console.WriteLine("[空调电费非数字]");
						}
					}
				}
				catch (Exception ex)
				{
					Console.WriteLine($"[出现异常]{ex.Message}");
					File.AppendAllText("./SendEleMsg.log", $"[出现异常]{ex.Message}\n" + $"[{System.DateTime.Now:G}]\n" + ex.StackTrace + "\n");
				}
				Console.WriteLine("------------------------------");
				Thread.Sleep(DelaySeconds * 1000);
			}
		}

		private static readonly List<string> Recipients = new();
		public static void InformUser(string title, string body)
		{
			Console.WriteLine("(即将发送提醒邮件)");
			SendMailSys.SendMail(title, body, Recipients);
		}

		[GeneratedRegex("window\\.location\\.replace\\(\"(?<JumpUrl>\\S+)\" \\+ url\\);")]
		private static partial Regex JumpUrlRegex();
	}
}
